import os

from PySide2 import QtWidgets
from PySide2.QtCore import QDateTime
from PySide2.QtGui import Qt
from PySide2.QtWidgets import QFileDialog, QMessageBox

from ui.tab_widget.upgrade_widget import Ui_UpgradeWidget
from utils.file_utils import Config
from utils.task import QTask


class Upgrade(QtWidgets.QWidget, Ui_UpgradeWidget):

    def __init__(self, parent):
        super(Upgrade, self).__init__(parent)
        self.setupUi(self)
        self.parent = parent

        self.radioButtonNetLink.toggled.connect(self.lineEditLink.setEnabled)
        self.radioButtonNetLink.toggled.connect(self.lineEditImgPath.setDisabled)
        self.radioButtonNetLink.toggled.connect(self.pushButtonSelImg.setDisabled)
        self.radioButtonLocal.toggled.connect(self.lineEditLink.setDisabled)
        self.radioButtonLocal.toggled.connect(self.lineEditImgPath.setEnabled)
        self.radioButtonLocal.toggled.connect(self.pushButtonSelImg.setEnabled)
        self.checkBoxUboot.clicked.connect(self.remind_user_risk)
        self.pushButtonSelImg.clicked.connect(self.select_img)
        self.task = QTask()

        self.download_progress = ''

    def remind_user_risk(self):
        if self.checkBoxUboot.checkState() == Qt.Checked:
            ans = QtWidgets.QMessageBox.warning(self, self.windowTitle(),
                                                '如果你的设备不是8G的设备，刷机时使用8G的uboot.img可能会导致设备变砖并且无法救机\n\n你确认要刷入8G的uboot.img吗？',
                                                QMessageBox.Yes | QMessageBox.Cancel)
            if ans != QMessageBox.Yes:
                self.checkBoxUboot.setCheckState(Qt.Unchecked)

    def select_img(self):
        file_path, _ = QFileDialog.getOpenFileName(self, '选择', os.path.dirname(self.lineEditImgPath.text()), '镜像包(*.tar.gz)', options=QFileDialog.DontUseNativeDialog)
        if not file_path:
            return
        self.lineEditImgPath.setText(os.path.realpath(file_path))

    def start_task(self):
        if len(self.parent.devices) != 1:
            QtWidgets.QMessageBox.warning(self, self.windowTitle(), '请确保有且仅有一台RK3568设备连接')
            return

        rk_img_save_path = Config.read_config().get('dayu200_path')
        if not rk_img_save_path or not os.path.exists(rk_img_save_path):
            QtWidgets.QMessageBox.warning(self, self.windowTitle(), '未知的rk镜像保存位置，请先设置正确的镜像保存位置')
            return

        device = self.parent.devices[0]
        if self.radioButtonNetLink.isChecked():
            url_link = self.lineEditLink.text().strip()
            if '/pulls/' in url_link:
                self.task.step_sgl.connect(self.show_upgrade_process)
                self.task.console_sgl.connect(self.show_console_log)
                self.task.send('upgrade_by_pr', device, url_link, rk_img_save_path, self.checkBoxUboot.isChecked())
            elif '/issues/' in url_link:
                self.task.step_sgl.connect(self.show_upgrade_process)
                self.task.console_sgl.connect(self.show_console_log)
                self.task.send('upgrade_by_issue', device, url_link, rk_img_save_path, self.checkBoxUboot.isChecked())
            elif url_link.startswith('http') and url_link.endswith('.tar.gz'):
                self.task.step_sgl.connect(self.show_upgrade_process)
                self.task.console_sgl.connect(self.show_console_log)
                self.task.send('upgrade_by_img_link', device, url_link, rk_img_save_path, self.checkBoxUboot.isChecked())
            else:
                QtWidgets.QMessageBox.warning(self, self.windowTitle(), '未知链接，请输入正确的链接地址')
        else:
            img_dir = self.lineEditImgPath.text().strip()
            if img_dir and os.path.isfile(img_dir) and img_dir.endswith('.tar.gz'):
                self.task.step_sgl.connect(self.show_upgrade_process)
                self.task.console_sgl.connect(self.show_console_log)
                self.task.send('upgrade_by_local_img', device, img_dir, self.checkBoxUboot.isChecked())
            else:
                QtWidgets.QMessageBox.warning(self, self.windowTitle(), '未知镜像，请输入正确的镜像地址')

    def show_upgrade_process(self, msg):
        current_time = QDateTime.currentDateTime().toString('hh:mm:ss')
        if msg.startswith('下载中'):
            html = self.textBrowser.toHtml()
            if not self.download_progress:
                self.download_progress = msg
                self.textBrowser.append('[{}] {}'.format(current_time, msg.replace('\n', '<br>')))
            else:
                new_html = html.replace(self.download_progress, msg)
                self.textBrowser.setHtml(new_html)
                self.download_progress = msg
        else:
            self.download_progress = ''
            if msg == '开始':
                self.start()
            elif msg == '结束' or msg == '异常':
                self.finish()
            else:
                self.textBrowser.append('[{}] {}'.format(current_time, msg.replace('\n', '<br>')))

    def show_console_log(self, console_log):
        self.textBrowserConsole.append(console_log.replace('\n', '<br>'))

    def start(self):
        self.parent.enter_busy()
        self.radioButtonNetLink.setEnabled(False)
        self.radioButtonLocal.setEnabled(False)
        self.checkBoxUboot.setEnabled(False)
        if self.radioButtonNetLink.isChecked():
            self.lineEditLink.setEnabled(False)
        if self.radioButtonLocal.isChecked():
            self.lineEditImgPath.setEnabled(False)
            self.pushButtonSelImg.setEnabled(False)
        self.textBrowser.clear()
        self.textBrowserConsole.clear()
        self.parent.statusbar.showMessage('刷机中，请保持设备处于连接状态...')

    def finish(self):
        self.parent.exit_busy()
        self.radioButtonNetLink.setEnabled(True)
        self.radioButtonLocal.setEnabled(True)
        self.checkBoxUboot.setEnabled(True)
        if self.radioButtonNetLink.isChecked():
            self.lineEditLink.setEnabled(True)
        if self.radioButtonLocal.isChecked():
            self.lineEditImgPath.setEnabled(True)
            self.pushButtonSelImg.setEnabled(True)
        self.parent.statusbar.clearMessage()
        self.task.step_sgl.disconnect(self.show_upgrade_process)
        self.task.console_sgl.disconnect(self.show_console_log)
